Double_t fgkTextSize = 0.05;
Double_t fgkTitleSize = 0.05;
Int_t fgkMarkerSize = 1;
Int_t fgkLineWidth = 2;
Int_t fgkTextFont = 42;
Double_t fgkLabelOffset = 0.01;
Double_t fgkXTitleOffset = 1.25;
Double_t fgkYTitleOffset = 1.2;
Double_t fgkTickLength = 0.02;

#define EPSILON 1e-12

void DividegPad(int nx, int ny,
                double l, double r, double t, double b)
{
  gStyle->SetPadTopMargin(0.);
  gStyle->SetPadBottomMargin(0.);
  gStyle->SetPadLeftMargin(0.);
  gStyle->SetPadRightMargin(0.); 
 
   int ix, iy, n=0;
   double x1, x2, y1, y2;
   double dx = ((1-r)*(1-l))/((1-r)*(1-l)*(nx-2)-r+2-l);
   double dl = dx/(1-l);
   double dy = ((1-t)*(1-b))/((1-t)*(1-b)*(ny-2)-t+2-b);
   double db = dy/(1-b);
   char *name  = new char [strlen(gPad->GetName())+6];

   y1 = 0;
   y2 = db;
   for (iy=0; iy<ny; iy++) {
      x1 = 0;
      x2 = dl;
      for (ix=0;ix<nx;ix++) {
         if (x1 > x2) continue;
         n++;
         sprintf(name,"%s_%d",gPad->GetName(),n);
         TPad *pad = new TPad(name,name,x1,y1,x2,y2,0);
         if (ix==0)    pad->SetLeftMargin(l);
         if (ix==nx-1) pad->SetRightMargin(r);
         if (iy==ny-1) pad->SetTopMargin(t);
         if (iy==0)    pad->SetBottomMargin(b);
         x1 = x2;
         if (ix==nx-2) x2 = 1;
         else          x2 = x1+dx;
         pad->SetNumber(n);
         pad->Draw();
         pad->SetTicks();
      }
      y1 = y2;
      if (iy==ny-2) y2 = 1;
      else          y2 = y1+dy;
   }
}

TGraphAsymmErrors * FilterGraph(const TGraphAsymmErrors * rawgr, const Double_t thres=-990)
{
  TGraphAsymmErrors * outgr = (TGraphAsymmErrors *) rawgr->Clone(Form("%sout", rawgr->GetName()));
  outgr->GetXaxis()->SetLimits(rawgr->GetXaxis()->GetXmin(), rawgr->GetXaxis()->GetXmax());
  Int_t jj = 0;
  for(Int_t ii=0; ii<rawgr->GetN(); ii++){
    const Double_t yy=rawgr->GetY()[ii];
    if(yy<thres){
      continue;
    }

    outgr->GetX()[jj]=rawgr->GetX()[ii];
    outgr->GetY()[jj]=rawgr->GetY()[ii];
    outgr->GetEYlow()[jj]=rawgr->GetEYlow()[ii];
    outgr->GetEYhigh()[jj]=rawgr->GetEYhigh()[ii];
    jj++;
  }
  outgr->Set(jj);

  return outgr;
}

void ToNaturalScale(TGraph* gr)
{
  for(Int_t ip=0; ip<gr->GetN(); ip++){
    Double_t xx=-999, yy=-999;
    gr->GetPoint(ip,xx,yy);
    gr->SetPoint(ip,TMath::Power(10,xx), yy);
  }
}

void ToNaturalScale(TGraphErrors* gr)
{
  for(Int_t ip=0; ip<gr->GetN(); ip++){
    Double_t xx=-999, yy=-999;
    gr->GetPoint(ip,xx,yy);
    //printf("%d %e %e\n",ip,xx,yy);
    gr->SetPoint(ip,TMath::Power(10,xx), yy);
  }
}

void ToNaturalScale(TAxis *ax)
{
  TAxis* oldx = (TAxis*)ax->Clone("oldx");
  ax->SetLimits(TMath::Power(10,oldx->GetXmin()), TMath::Power(10,oldx->GetXmax()));
  const Int_t nb = oldx->GetNbins();
  Double_t *bins = new Double_t[nb+1];
  for(Int_t ii=1; ii<=nb; ii++){
    bins[ii]=TMath::Power(10,oldx->GetBinUpEdge(ii));
  }
  ax->Set(nb, bins);

  delete oldx;
  delete bins;
}

void ToNaturalScale(TH1 *hh)
{
  ToNaturalScale(hh->GetXaxis());
}

void BinLogX(TAxis *axis) 
{
  //
  // Method for the correct logarithmic binning of histograms
  // copied and modified from AliTPCcalibBase

  const Int_t bins = axis->GetNbins();

  const Double_t from = axis->GetXmin();
  const Double_t to = axis->GetXmax();
  if (from<EPSILON) return;
  Double_t *new_bins = new Double_t[bins + 1];

  new_bins[0] = from;
  const Double_t factor = TMath::Power(to/from, 1./bins);

  for (int i = 1; i <= bins; i++) {
   new_bins[i] = factor * new_bins[i-1];
  }
  axis->Set(bins, new_bins);
  delete [] new_bins;
}

void UpdateLogX(TH1 *obj)
{
  TAxis * axis = obj->GetXaxis();
  double xmin = axis->GetXmin();
  double xmax = axis->GetXmax();
  axis->SetLimits(TMath::Power(10,xmin), TMath::Power(10,xmax));
  BinLogX(axis);
}

void UpdateLogX(TGraphAsymmErrors *obj)
{
  const Int_t np = obj->GetN();
  for(Int_t ii=0; ii<np; ii++){
    Double_t xx =-999, yy=-999;
    obj->GetPoint(ii,xx,yy);
    Double_t ex0 = obj->GetErrorXlow(ii);
    Double_t ex1 = obj->GetErrorXhigh(ii);
    const Double_t ey0 = obj->GetErrorYlow(ii);
    const Double_t ey1 = obj->GetErrorYhigh(ii);

    ex0 = TMath::Power(10, xx) - TMath::Power(10, xx-ex0);
    ex1 = TMath::Power(10, xx+ex1) - TMath::Power(10, xx);
    xx = TMath::Power(10, xx);

    obj->SetPoint(ii, xx, yy);
    obj->SetPointError(ii, ex0, ex1, ey0, ey1);
  }
}


void UpdateLogX(TGraphErrors *obj)
{
  const Int_t np = obj->GetN();
  for(Int_t ii=0; ii<np; ii++){
    Double_t xx =-999, yy=-999;
    obj->GetPoint(ii,xx,yy);
    Double_t ex = obj->GetErrorX(ii);
    const Double_t ey = obj->GetErrorY(ii);

    ex = TMath::Power(10, xx) - TMath::Power(10, xx-ex);
    xx = TMath::Power(10, xx);

    obj->SetPoint(ii, xx, yy);
    obj->SetPointError(ii, ex, ey);
  }
}


void PadSetup(TPad *currentPad, const Double_t currentLeft=0.12, const Double_t currentTop=0.09, const Double_t currentRight=0.13, const Double_t currentBottom=0.14)
{
  currentPad->SetTicks(1,1);
  currentPad->SetLeftMargin(currentLeft);
  currentPad->SetTopMargin(currentTop);
  currentPad->SetRightMargin(currentRight);
  currentPad->SetBottomMargin(currentBottom);

  currentPad->SetFillColor(0);//this is the desired one!!!
}

void AxisStyle(TAxis *ax, Bool_t kcen=0)
{
  ax->SetTickLength(fgkTickLength);

  ax->SetLabelFont(fgkTextFont);
  ax->SetLabelSize(fgkTextSize);
  ax->SetLabelOffset(fgkLabelOffset);

  ax->SetTitleFont(fgkTextFont);
  ax->SetTitleSize(fgkTitleSize);

  ax->CenterTitle(kcen);
}

void ResetStyle(TLegend *obj, Double_t mar=-999)
{
  if(mar>0){
    obj->SetMargin(mar);
  }
  obj->SetFillStyle(-1);
  obj->SetBorderSize(-1);
  obj->SetTextFont(fgkTextFont);
  obj->SetTextSize(fgkTextSize*0.8);
}

void ResetStyle(TLatex *obj, const Double_t ff=1)
{
  obj->SetNDC();
  obj->SetTextFont(fgkTextFont);
  obj->SetTextSize(fgkTextSize*ff);
}

void ResetStyle(TGraph *obj)
{
  obj->SetMarkerSize(fgkMarkerSize);

  AxisStyle(obj->GetXaxis());
  AxisStyle(obj->GetYaxis());

  obj->GetXaxis()->SetTitleOffset(fgkXTitleOffset);
  obj->GetYaxis()->SetTitleOffset(fgkYTitleOffset);
}

void ResetStyle(TF1 * obj, Bool_t kcen=0)
{
  obj->SetMarkerSize(fgkMarkerSize);

  AxisStyle(obj->GetXaxis(), kcen);
  AxisStyle(obj->GetYaxis(), kcen);

  obj->GetXaxis()->SetTitleOffset(fgkXTitleOffset);
  obj->GetYaxis()->SetTitleOffset(fgkYTitleOffset);
}

void ResetStyle(TH1 * obj, TPad* cpad=0x0, Bool_t kcen=0)
{
  obj->SetMarkerSize(fgkMarkerSize);

  AxisStyle(obj->GetXaxis(), kcen);
  AxisStyle(obj->GetYaxis(), kcen);

  obj->GetXaxis()->SetTitleOffset(fgkXTitleOffset);
  obj->GetYaxis()->SetTitleOffset(fgkYTitleOffset);

  if(cpad){
    TPaletteAxis *palette = (TPaletteAxis*)obj->GetListOfFunctions()->FindObject("palette");
    if(!palette){
      printf("ResetStyle no palette!!\n"); 
      obj->GetListOfFunctions()->Print();
    }
    else{
      palette->SetX1NDC(1-cpad->GetRightMargin()+0.005);
      palette->SetX2NDC(1-cpad->GetRightMargin()/3*2);
      palette->SetY1NDC(cpad->GetBottomMargin());
      palette->SetY2NDC(1-cpad->GetTopMargin());
      palette->SetLabelFont(fgkTextFont);
      palette->SetLabelSize(fgkTextSize);
      palette->SetLabelOffset(fgkLabelOffset);
    }
  }

}

void DrawLogo(TCanvas *cc, const Double_t x0, const Double_t y0, const TString tag)
{
  TPad *lpad=new TPad("lpad", "", x0,y0,x0+0.13,y0+0.2);
  PadSetup(lpad,0,0,0,0);
  lpad->Draw();
  lpad->cd();
  TASImage *logo = new TASImage("/u/xlu/.code/trunk/inc/2011-Nov-24-ALICE_PERFORMANCE_logo_BLACK_small_usage_design.eps");
  logo->Draw();

  cc->cd();
  TLatex * date = new TLatex(x0, y0-0.05, tag);
  ResetStyle(date, 0.8);
  date->Draw();
}

void SetColor()
{
  gStyle->SetHistFillColor(0);
  //gStyle->SetFillColor(0);//it conflicts with color palette
  gStyle->SetFrameFillColor(0);
  gStyle->SetPadColor(0);
  gStyle->SetCanvasColor(0);
  gStyle->SetStatColor(0);
  gStyle->SetTitleFillColor(0);

  //---

  const Int_t nRGBs = 5;
  const Int_t nCont = 100;
  Double_t stops[nRGBs] = { 0.00, 0.34, 0.61, 0.84, 1.00 };
  Double_t red[nRGBs]   = { 0.00, 0.00, 0.87, 1.00, 0.51 };
  Double_t green[nRGBs] = { 0.00, 0.81, 1.00, 0.20, 0.00 };
  Double_t blue[nRGBs]  = { 0.51, 1.00, 0.12, 0.00, 0.00 };
  const Int_t cgc = TColor::CreateGradientColorTable(nRGBs, stops, red, green, blue, nCont);

  const Int_t nc = nCont;
  Int_t colors[nc];
  gStyle->SetNumberContours(nc); 
  for(Int_t ii=0; ii<nc; ii++){
    colors[ii]=cgc+ii;
  }
  gStyle->SetPalette(nc, colors);
}

void SetGlobalStyle(const Int_t lStat=0, Bool_t kcolor = 1)
{
  // Set gStyle
  // From plain

  gStyle->SetFrameBorderMode(0);
  gStyle->SetFrameFillColor(0);
  gStyle->SetCanvasBorderMode(0);
  gStyle->SetPadBorderMode(0);
  gStyle->SetPadColor(10);
  gStyle->SetCanvasColor(10);
  gStyle->SetTitleFillColor(10);
  gStyle->SetTitleBorderSize(-1);
  gStyle->SetStatColor(10);
  gStyle->SetStatBorderSize(-1);
  gStyle->SetLegendBorderSize(-1);
  //
  gStyle->SetDrawBorder(0);
  gStyle->SetTextFont(fgkTextFont);
  gStyle->SetStatFont(fgkTextFont);
  gStyle->SetStatFontSize(fgkTextSize);
  gStyle->SetStatX(0.97);
  gStyle->SetStatY(0.98);
  gStyle->SetStatH(0.03);
  gStyle->SetStatW(0.3);
  gStyle->SetTickLength(fgkTickLength,"xy");
  gStyle->SetEndErrorSize(3);
  gStyle->SetLabelSize(fgkTextSize,"xyz");
  gStyle->SetLabelFont(fgkTextFont,"xyz"); 
  gStyle->SetLabelOffset(fgkLabelOffset,"xyz");
  gStyle->SetTitleFont(fgkTextFont,"xyz");  
  gStyle->SetTitleFont(fgkTextFont,"");  
  gStyle->SetTitleFontSize(fgkTitleSize);
  gStyle->SetTitleOffset(fgkXTitleOffset,"x");  
  gStyle->SetTitleOffset(fgkYTitleOffset,"y");  
  gStyle->SetTitleOffset(1.0,"z");  
  gStyle->SetTitleSize(fgkTitleSize,"xyz");  
  gStyle->SetTitleSize(fgkTitleSize,"");  
  gStyle->SetMarkerSize(fgkMarkerSize); 
  gStyle->SetPalette(1,0); 
  if (lStat){
    gStyle->SetOptTitle(1);
    gStyle->SetOptStat(1111);
    gStyle->SetOptFit(1111);
    }
  else {
    gStyle->SetOptTitle(0);
    gStyle->SetOptStat(0);
    gStyle->SetOptFit(0);
  }

  TGaxis::SetMaxDigits(3);
  gStyle->SetTitleBorderSize(-1);

  if(kcolor){
    SetColor();
  }

  gROOT->ForceStyle();
}

  
